package hu.uniobuda.nik.bsik2f.FileBrowser;

import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.*;

import java.io.File;
import java.io.FileFilter;

import static android.widget.AdapterView.OnItemClickListener;
import static android.widget.AdapterView.OnItemLongClickListener;

/**
 * Created with IntelliJ IDEA.
 * User: Matusinka Roland
 * Date: 2013.03.13.
 * Time: 16:49
 */

public class BrowserActivity extends Activity {

    //<editor-fold desc="Publics">
    public static final int MODE_OPEN_FILE = 67363453;
    public static final int MODE_SELECT_DIR = 735328347;
    public static final int MODE_SAVE_FILE = 72833453;
    public static final int SORT_BY_NAME = 296263;
    public static final int LAYOUT_LIST = 5478;
    public static final int LAYOUT_GRID = 4743;
    //public static final int SORT_BY_XXX = 29XXXX;
    public static final String OPTION_BROWSE_MODE = "browseMode";   //Tallózás módja: Fájl megnyitása|Fájl mentése|Mappa megnyitása (Alapértelmezett: fájl megnyitása)
    public static final String OPTION_START_PATH = "startPath"; //Kezdőmappa abszolút elérési útja (Alapértelmezett: "/")
    public static final String OPTION_EXTENSION_FILTER = "extensionFilter"; //Engedélyezett kiterjesztések pontosvesszővel (;) elválasztva (Alapértelmezett: üres)
    public static final String RESULT = "result"; //Visszatérési érték: a kiválasztott fájl/mappa abszolút elérési útja
    public static final String OPTION_SORT_MODE = "sort"; //Rendezési mód (Alapértelmezett: fájlnév szerint (mappák mindig elöl))
    public static final String OPTION_DEFAULT_FILENAME = "defaultFileName"; //Megadható alapértelmezett fájlnév mentéshez (Alapértelmezett: üres)
    public static final String OPTION_START_IS_ROOT = "startIsRoot"; //A megadott kezdőmappát tekintse gyökérnek; nem engedi a felhasználót feljebb tallózni.
    public static final String OPTION_LAYOUT = "layout";
    //</editor-fold>
    //<editor-fold desc="Privates">
    private String currentPath;
    private AbsListView list;
    private Intent resultIntent;
    private int browseMode;
    private int sortMode;
    private String[] extensionFilter;
    private String defaultFileName;
    private String startPath;
    private boolean startIsRoot;
    private int activeLayout;
    private TextView tvCurrentPath;
    private boolean longPress;
    private int itemLayoutID;
    private MenuItem viewAs;
    private ImageButton imgbtnSave;
    private EditText etFilename;
    private ViewFlipper vf;
    //</editor-fold>

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //<editor-fold desc="Init variables">
        final Intent inputIntent = getIntent();
        setResult(RESULT_CANCELED, resultIntent);
        browseMode = inputIntent.getIntExtra(OPTION_BROWSE_MODE, MODE_OPEN_FILE);
        startPath = (inputIntent.getStringExtra(OPTION_START_PATH) != null) ?
                inputIntent.getStringExtra(OPTION_START_PATH) : "/";
        currentPath = startPath;
        if (inputIntent.getStringExtra(OPTION_EXTENSION_FILTER) != null)
            extensionFilter = inputIntent.getStringExtra(OPTION_EXTENSION_FILTER).split(";");
        sortMode = inputIntent.getIntExtra(OPTION_SORT_MODE, SORT_BY_NAME);
        defaultFileName = (inputIntent.getStringExtra(OPTION_DEFAULT_FILENAME) != null) ?
                inputIntent.getStringExtra(OPTION_DEFAULT_FILENAME) : getResources().getString(R.string.filename_placeholder);
        startIsRoot = inputIntent.getBooleanExtra(OPTION_START_IS_ROOT, true);
        activeLayout = inputIntent.getIntExtra(OPTION_LAYOUT, LAYOUT_LIST);
        switch (activeLayout) {
            default:
            case LAYOUT_LIST:
                itemLayoutID = R.layout.browser_listitem_layout;
                break;
            case LAYOUT_GRID:
                itemLayoutID = R.layout.browser_griditem_layout;
                break;
        }
        //</editor-fold>

        switch (browseMode) {
            default:
            case MODE_OPEN_FILE:
                setContentView(R.layout.browser_layout);
                setTitle(R.string.browser_title_openfile);
                break;
            case MODE_SELECT_DIR:
                setContentView(R.layout.browser_layout);
                setTitle(R.string.browser_title_selectdir);
                break;
            case MODE_SAVE_FILE:
                setContentView(R.layout.browser_layout_save);
                setTitle(R.string.browser_title_savefile);
                break;
        }

        if (Build.VERSION.SDK_INT >= 11) {
            ActionBar actionBar = getActionBar();
            switch (browseMode) {
                default:
                case MODE_OPEN_FILE:
                    actionBar.setTitle(R.string.browser_title_openfile);
                    actionBar.setIcon(R.drawable.browser_folder_open);
                    break;
                case MODE_SELECT_DIR:
                    actionBar.setTitle(R.string.browser_title_selectdir);
                    actionBar.setIcon(R.drawable.browser_folder_open);
                    break;
                case MODE_SAVE_FILE:
                    actionBar.setTitle(R.string.browser_title_savefile);
                    actionBar.setIcon(R.drawable.browser_save_title);
                    break;
            }
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
    }

    @Override
    protected void onStart() {
        super.onStart();

        tvCurrentPath = (TextView) findViewById(R.id.textViewCurrentDir);

        switch (activeLayout) {
            default:
            case LAYOUT_LIST:
                toListView();
                break;
            case LAYOUT_GRID:
                toGridView();
                break;
        }

        if (browseMode == MODE_SAVE_FILE) {
            imgbtnSave = (imgbtnSave == null) ? (ImageButton) findViewById(R.id.imageButtonSave) : imgbtnSave;
            etFilename = (etFilename == null) ? (EditText) findViewById(R.id.editTextFilename) : etFilename;
            if (defaultFileName != null) etFilename.setText(defaultFileName);
            etFilename.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
                }

                @Override
                public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
                    imgbtnSave.setEnabled(!charSequence.toString().equals(""));
                }

                @Override
                public void afterTextChanged(Editable editable) {
                }
            });
            imgbtnSave.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    String fileName = currentPath + "/" + etFilename.getText();
                    File f = new File(fileName);
                    if (f.exists()) {
                        showOverwriteDialog(fileName);
                    } else {
                        ok(fileName);
                    }
                }
            });
        }
        //TODO: képernyődöntéskor ne kezdje elölről
    }

    private void setListeners() {
        switch (browseMode) {
            default:
            case MODE_OPEN_FILE:
                list.setOnItemClickListener(new OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                        FileHolder holder = (FileHolder) view.getTag();
                        if (holder.file.isDirectory()) LoadList(holder.file);
                        if (holder.file.isFile()) {
                            ok(holder.file.getAbsolutePath());
                        }
                    }
                });
                list.setOnItemLongClickListener(new OnItemLongClickListener() {
                    @Override
                    public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
                        FileHolder holder = (FileHolder) view.getTag();
                        if (holder.file.isFile()) {
                            ok(holder.file.getAbsolutePath());
                        }
                        return holder.file.isFile();
                    }
                });
                break;
            case MODE_SELECT_DIR:
                list.setOnItemClickListener(new OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                        FileHolder holder = (FileHolder) view.getTag();
                        if (holder.file.isDirectory()) LoadList(holder.file);

                    }
                });
                list.setOnItemLongClickListener(new OnItemLongClickListener() {
                    @Override
                    public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
                        FileHolder holder = (FileHolder) view.getTag();
                        ok(holder.file.getAbsolutePath());
                        return true;
                    }
                });
                break;
            case MODE_SAVE_FILE:
                list.setOnItemClickListener(new OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                        FileHolder holder = (FileHolder) view.getTag();
                        if (holder.file.isFile()) etFilename.setText(holder.file.getName());
                        if (holder.file.isDirectory()) LoadList(holder.file);
                    }
                });
                list.setOnItemLongClickListener(new OnItemLongClickListener() {
                    @Override
                    public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
                        FileHolder holder = (FileHolder) view.getTag();
                        if (!holder.file.isFile()) return false;
                        else {
                            showOverwriteDialog(holder.file.getAbsolutePath());
                            return true;
                        }
                    }
                });
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.browser_menu, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        viewAs = menu.findItem(R.id.menu_viewAs);
        switch (activeLayout) {
            default:
            case LAYOUT_LIST:
                viewAs.setIcon(R.drawable.browser_view_as_grid);
                viewAs.setTitle(R.string.menu_viewAsGrid);
                break;
            case LAYOUT_GRID:
                viewAs.setIcon(R.drawable.browser_view_as_list);
                viewAs.setTitle(R.string.menu_viewAsList);
                break;
        }
        return super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                cancel();
                break;
            case R.id.menu_viewAs:
                changeLayout();
                break;
            case R.id.menu_newFolder:
                createNewFolder();
                break;
            case R.id.menu_sortBy:
                changeSortMode();
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    private void changeSortMode() {
        //TODO: implement method
    }

    private void createNewFolder() {
        //TODO: implement method
    }

    private void changeLayout() {
        switch (activeLayout) {
            default:
            case LAYOUT_LIST:
                toGridView();
                viewAs.setIcon(R.drawable.browser_view_as_list);
                viewAs.setTitle(R.string.menu_viewAsList);
                break;
            case LAYOUT_GRID:
                toListView();
                viewAs.setIcon(R.drawable.browser_view_as_grid);
                viewAs.setTitle(R.string.menu_viewAsGrid);
                break;
        }
        setListeners();
        LoadList(new File(currentPath));
        if (Build.VERSION.SDK_INT >= 11) {
            VersionHelper.refreshActionBarMenu(this);
        }
    }

    private void toListView() {
        vf = (vf == null) ? (ViewFlipper) findViewById(R.id.viewFlipper) : vf;
        if (vf.getDisplayedChild() == 1) {
            vf.showNext();
        }
        activeLayout = LAYOUT_LIST;
        list = (ListView) findViewById(R.id.listView);
        itemLayoutID = R.layout.browser_listitem_layout;
        setListeners();
        LoadList(new File(currentPath));
        Log.d("bsik2f", "Switched to LIST.");
    }

    private void toGridView() {
        vf = (vf == null) ? (ViewFlipper) findViewById(R.id.viewFlipper) : vf;
        if (vf.getDisplayedChild() == 0) {
            vf.showNext();
        }
        activeLayout = LAYOUT_GRID;
        list = (GridView) findViewById(R.id.gridView);
        itemLayoutID = R.layout.browser_griditem_layout;
        setListeners();
        LoadList(new File(currentPath));
        Log.d("bsik2f", "Switched to GRID.");
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            longPress = false;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyLongPress(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            longPress = true;
            cancel();
            return true;
        }
        return super.onKeyLongPress(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (!longPress) {
                if (!currentPath.equals((startIsRoot) ? startPath : "/"))
                    LoadList(new File(currentPath).getParentFile());
                else
                    Toast.makeText(getApplicationContext(), getResources().getString(R.string.toast_noParentDir), Toast.LENGTH_SHORT).show();
            }
            return true;
        }
        return super.onKeyUp(keyCode, event);
    }

    private void ok(String path) {
        resultIntent = new Intent();
        resultIntent.putExtra(BrowserActivity.RESULT, path);
        setResult(RESULT_OK, resultIntent);
        finish();
    }

    void LoadList(final File file) {
        currentPath = file.getAbsolutePath();
        File[] filesToLoad;

        tvCurrentPath.setText(currentPath);

        if (extensionFilter != null) {
            FileFilter filterToUse = new FileFilter() {
                @Override
                public boolean accept(File file) {
                    if (file.isFile()) {
                        String ext = Utils.getExtension(file.getName());
                        int i = 0;
                        int n = extensionFilter.length;
                        while (i < n && !extensionFilter[i].toLowerCase().equals(ext)) i++;
                        return i < n;
                    } else return file.isDirectory();
                }
            };
            filesToLoad = file.listFiles(filterToUse);
        } else filesToLoad = file.listFiles();

        FileListAdapter fla;

        switch (browseMode) {
            default:
            case MODE_SAVE_FILE:
            case MODE_OPEN_FILE:
                fla = new FileListAdapter(this, itemLayoutID, filesToLoad, sortMode);
                break;
            case MODE_SELECT_DIR:
                fla = new FileListAdapter(this, itemLayoutID, file.listFiles(new FileFilter() {
                    @Override
                    public boolean accept(File file) {
                        return file.isDirectory();
                    }
                }), sortMode);
                break;
        }

        list.setAdapter(fla);
    }

    private void showOverwriteDialog(final String fileName) {
        AlertDialog.Builder builder = new AlertDialog.Builder(BrowserActivity.this)
                .setIcon(android.R.drawable.ic_dialog_alert)
                .setMessage(R.string.overwrite)
                .setTitle(R.string.file_exists)
                .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        ok(fileName);
                    }
                })
                .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        dialogInterface.dismiss();
                    }
                });
        AlertDialog ad = builder.create();
        ad.show();
    }

    private void cancel() {
        setResult(RESULT_CANCELED, resultIntent);
        finish();
    }
}

class VersionHelper {
    static void refreshActionBarMenu(Activity activity) {
        activity.invalidateOptionsMenu();
    }
}